package board

import (
	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
	"github.com/flipped-aurora/gin-vue-admin/server/model/wearingparts"
	"time"

	"github.com/gin-gonic/gin"
)

type BoardApi struct{}

// GetDashboardData 获取看板数据
// @Tags      Board
// @Summary   获取看板数据
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     startTime  query     int                          false  "开始时间戳"
// @Param     endTime    query     int                          false  "结束时间戳"
// @Param     timeType   query     string                       false  "时间类型(day/week/month)"
// @Success   200        {object}  response.Response{data=map[string]interface{}}  "获取看板数据成功"
// @Router    /api/dashboard/data [get]
func (b *BoardApi) GetDashboardData(c *gin.Context) {
	var req struct {
		StartTime int64  `form:"startTime"`
		EndTime   int64  `form:"endTime"`
		TimeType  string `form:"timeType" default:"month"`
	}

	if err := c.ShouldBindQuery(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 处理时间范围
	startTime := time.Unix(req.StartTime/1000, 0)
	endTime := time.Unix(req.EndTime/1000, 0)

	// 查询总更换次数
	var totalReplacements int64
	global.GVA_DB.Model(&wearingparts.Erotable{}).
		Where("operation_date BETWEEN ? AND ?", startTime, endTime).
		Count(&totalReplacements)

	// 查询平均更换周期
	var avgCycleDays float64
	global.GVA_DB.Model(&wearingparts.Erotable{}).
		Where("operation_date BETWEEN ? AND ?", startTime, endTime).
		Select("AVG(operation_days)").
		Row().
		Scan(&avgCycleDays)

	// 查询TOP5部件
	var topParts []struct {
		EroPartModel string  `json:"partModel"`
		Count        int     `json:"count"`
		Percentage   float64 `json:"percentage"`
	}

	// 子查询计算总更换次数
	subQuery := global.GVA_DB.Model(&wearingparts.Erotable{}).
		Where("operation_date BETWEEN ? AND ?", startTime, endTime).
		Select("COUNT(*)")

	// 查询TOP5部件及占比
	global.GVA_DB.Model(&wearingparts.Erotable{}).
		Select("ero_part_model, COUNT(*) as count, (COUNT(*) * 100.0 / (?)) as percentage", subQuery).
		Where("operation_date BETWEEN ? AND ?", startTime, endTime).
		Group("ero_part_model").
		Order("count DESC").
		Limit(5).
		Find(&topParts)

	// 趋势分析数据
	var trendData []struct {
		Date  string `json:"date"`
		Count int    `json:"count"`
	}

	// 根据时间类型确定分组方式
	var groupBy string
	switch req.TimeType {
	case "day":
		groupBy = "DATE_FORMAT(operation_date, '%Y-%m-%d')"
	case "week":
		groupBy = "DATE_FORMAT(operation_date, '%Y-%u')"
	default: // month
		groupBy = "DATE_FORMAT(operation_date, '%Y-%m')"
	}

	// 查询趋势数据
	global.GVA_DB.Model(&wearingparts.Erotable{}).
		Select("? as date, COUNT(*) as count", groupBy).
		Where("operation_date BETWEEN ? AND ?", startTime, endTime).
		Group("date").
		Order("date ASC").
		Find(&trendData)

	// 部件类型分布
	var typeData []struct {
		Name  string `json:"name"`
		Value int    `json:"value"`
	}

	// 假设ero_part_model的前两位代表类型
	global.GVA_DB.Model(&wearingparts.Erotable{}).
		Select("SUBSTRING(ero_part_model, 1, 2) as name, COUNT(*) as value").
		Where("operation_date BETWEEN ? AND ?", startTime, endTime).
		Group("name").
		Find(&typeData)

	// 构建响应数据
	data := map[string]interface{}{
		"totalReplacements": totalReplacements,
		"averageCycleDays":  avgCycleDays,
		"topParts":          topParts,
		"trendData":         trendData,
		"typeData":          typeData,
	}

	response.OkWithDetailed(data, "获取看板数据成功", c)
}

// GetErotableList 获取ERO部件更换记录列表
// @Tags      Board
// @Summary   获取ERO部件更换记录列表
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     page        query     int                             false  "页码"
// @Param     pageSize    query     int                             false  "每页条数"
// @Param     searchKey   query     string                          false  "搜索关键词"
// @Param     startTime   query     int                             false  "开始时间戳"
// @Param     endTime     query     int                             false  "结束时间戳"
// @Success   200         {object}  response.Response{data=response.PageResult{list=[]system.Erotable,total=integer}}  "获取ERO部件更换记录列表成功"
// @Router    /api/ero/table/list [get]
func (b *BoardApi) GetErotableList(c *gin.Context) {
	var req struct {
		request.PageInfo
		SearchKey string `form:"searchKey"`
		StartTime int64  `form:"startTime"`
		EndTime   int64  `form:"endTime"`
	}

	if err := c.ShouldBindQuery(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 构建查询条件
	db := global.GVA_DB.Model(&wearingparts.Erotable{})

	// 搜索关键词
	if req.SearchKey != "" {
		db = db.Where("ero_part_model LIKE ? OR ero_part_id LIKE ?",
			"%"+req.SearchKey+"%", "%"+req.SearchKey+"%")
	}

	// 时间范围
	if req.StartTime > 0 && req.EndTime > 0 {
		startTime := time.Unix(req.StartTime/1000, 0)
		endTime := time.Unix(req.EndTime/1000, 0)
		db = db.Where("operation_date BETWEEN ? AND ?", startTime, endTime)
	}

	// 分页
	var list []wearingparts.Erotable
	var total int64

	// 计算总数
	if err := db.Count(&total).Error; err != nil {
		response.FailWithMessage("获取总数失败", c)
		return
	}

	// 查询列表
	limit := req.PageSize
	offset := req.PageSize * (req.Page - 1)

	if err := db.Limit(limit).Offset(offset).Order("operation_date DESC").Find(&list).Error; err != nil {
		response.FailWithMessage("获取列表失败", c)
		return
	}

	response.OkWithDetailed(response.PageResult{
		List:     list,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}, "获取ERO部件更换记录列表成功", c)
}
